<template>
  <el-dialog
    v-model="centerDialogVisible"
    :title="props.title"
    :width="props.width"
    align-center
    draggable
    destroy-on-close
    :close-on-click-modal="false"
  >
    <el-scrollbar :height="props.height">
      <el-form
        :rules="rules"
        :model="formData"
        ref="ruleFormRef"
        status-icon
        :inline="props.inline"
        :label-width="props.labelWidth"
        :label-position="props.labelPosition"
      >
        <slot :form="formData"></slot>
      </el-form>
    </el-scrollbar>
    <template #footer>
      <div class="dialog-footer">
        <el-button-group>
          <el-button @click="centerDialogVisible = false">{{ t('common.close') }}</el-button>
          <el-button type="primary" @click="submit">
            {{ t('common.submit') }}
          </el-button>
        </el-button-group>
      </div>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { reactive, ref, unref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { FormInstance, FormRules, ElMessage, FormItemRule, ElLoading } from 'element-plus'
import request from '@/axios'
import { GetParamsType, FormDataType, WsmFormPropsType } from './types'
import { rulesApi } from '@/api/dbms/requestvalid'
import { ruleConfig } from './types/ruleConfig'

const { t } = useI18n()

const rules = ref<FormRules<FormDataType>>({})

//表单对象
const ruleFormRef = ref<FormInstance>()

//绑定的v-model
const formModel = defineModel<FormDataType>()

//获取配置参数
const props = withDefaults(defineProps<WsmFormPropsType>(), {
  width: '50%',
  inline: false,
  labelWidth: 'auto',
  labelPosition: 'top',
  ruleCode: 'default',
  beforeLoad: (_formData: FormDataType, data) => {
    return data
  },
  beforeSubmit: (data: FormDataType) => {
    return data
  }
})

//加载校验信息
const loadRules = async () => {
  const rs = await rulesApi({ code: props.ruleCode, url: props.submitUrl })
  if (rs.success) {
    //构建rule
    const data = rs.data
    data.forEach((item) => {
      const key = item.paramKey
      const crules: FormItemRule[] = []
      item.configs.forEach((config) => {
        if (config.validClass == 'org.scboy.dbms.valid.common.EmptyValid') {
          crules.push({ required: true, message: t('validate.required'), trigger: 'blur' })
        } else {
          crules.push({
            validator: (_rule: any, value: any, callback: any) => {
              if (value === '') {
                callback()
              } else {
                const valid = ruleConfig[config.validClass](config, value, unref(formData))
                if (valid.check) {
                  callback()
                } else {
                  if (valid.params) {
                    callback(new Error(t(valid.msg, valid.params)))
                  } else {
                    callback(new Error(t(valid.msg)))
                  }
                }
              }
            },
            trigger: 'blur'
          })
        }
      })
      if (crules.length > 0) {
        rules.value[key] = crules
      }
    })
  }
}

loadRules()
//定义事件
const emit = defineEmits({
  success: (data: FormDataType) => {
    return data
  }
})

//把v-model转换为formData
const formData = reactive<FormDataType>(formModel.value ? unref(formModel.value) : {})

const clearForm = (defalut?: FormDataType) => {
  let checkForm = props.initData || {}
  checkForm = JSON.parse(JSON.stringify(checkForm))
  checkForm = defalut ? defalut : checkForm
  //
  for (const key in formData) {
    if (checkForm[key]) {
      formData[key] = checkForm[key]
    } else {
      formData[key] = ''
    }
  }
}

const centerDialogVisible = ref(false)

//提交，并校验数据格式
const submit = async () => {
  await ruleFormRef.value?.validate((valid) => {
    if (valid) {
      submitApi()
    }
  })
}

//提交表单
const submitApi = async () => {
  const submitData = props.beforeSubmit(unref(formData))
  const loading = ElLoading.service({
    lock: true,
    text: t('common.submitMessage'),
    background: 'rgba(0, 0, 0, 0.7)'
  })
  if (props.loadUrl) {
    const rs = await request.put({ url: props.submitUrl, data: submitData }, loading)
    if (rs.success) {
      ElMessage.success(rs.message)
      centerDialogVisible.value = false
      //成功回调
      emit('success', rs.data)
    }
  } else {
    const rs = await request.post({ url: props.submitUrl, data: submitData }, loading)
    if (rs.success) {
      ElMessage.success(rs.message)
      centerDialogVisible.value = false
      //成功回调
      emit('success', rs.data)
    }
  }
}

//打开表单
const show = async (params: GetParamsType) => {
  //清空表单
  clearForm()
  //加载数据，如果加载的话。
  if (props.loadUrl) {
    const loading = ElLoading.service({
      lock: true,
      text: t('common.loadMessage'),
      background: 'rgba(0, 0, 0, 0.7)'
    })
    const rs = await request.get({ url: props.loadUrl, params }, loading)
    if (rs) {
      //赋值
      for (const key in formData) {
        formData[key] = rs.data[key]
      }
      props.beforeLoad(formData, rs.data)
      //显示表单
      centerDialogVisible.value = true
    } else {
      ElMessage.error(t('common.loadError'))
    }
  } else {
    //显示表单
    centerDialogVisible.value = true
  }
}

//关闭表单
const hide = () => {
  centerDialogVisible.value = false
}

const getFormData = () => {
  return formData
}

//暴露方法
defineExpose({ show, hide, clearForm, getFormData })
</script>
<style scoped>
:deep(.el-form--label-top .el-form-item) {
  display: block;
  margin-right: 10px;
}
</style>
